/*
 * Copyright (c) 2015 Messcat. All rights reserved.
 */
package cc.messcat.service.system;

import cc.messcat.common.constant.CommonConstant;
import cc.messcat.common.model.Pager;
import cc.messcat.common.security.token.SecurityHandler;
import cc.messcat.common.service.BaseServiceImpl;
import cc.messcat.common.util.BeanUtil;
import cc.messcat.common.util.CollectionUtil;
import cc.messcat.common.util.StringUtil;
import cc.messcat.dao.area.AreaDao;
import cc.messcat.dao.system.RoleDao;
import cc.messcat.dao.system.UserDao;
import cc.messcat.entity.area.Area;
import cc.messcat.entity.system.McUser;
import cc.messcat.entity.system.Permission;
import cc.messcat.entity.system.Role;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpSession;
import java.util.*;

/**
 * 用户接口实现
 *
 * @author Microcat
 * @version 1.0
 */
@Service
@RequestMapping("/user")
public class UserServiceImpl extends BaseServiceImpl<McUser> implements UserService {

    @Autowired
    private UserDao userDao;

    @Autowired
    private RoleDao roleDao;

    @Autowired
    private AreaDao areaDao;

    public McUser retrieveUserById(Long id) {
        McUser user = retrieveObject(id);
        if (user != null) {
            user.setPassword(null);
            user.setRoles(null);
        }
        return user;
    }

    public McUser retrieveUserByIdWithoutPermission(Long id) {
        McUser user = retrieveObject(id);
        if (user != null) {
            user.setPassword(null);
            Set<Role> role = user.getRoles();
            if (null != role) {
                for (Role aRole : role) {
                    aRole.setPermissions(null);
                }
            }
        }
        return user;
    }

    @Override
    public McUser retrieveUserByUsernameIgnorePassword(String username) {
        McUser user = userDao.getUserByUsername(username);
        if (user != null) {
            user.setPassword(null);
        }
        return user;
    }

    @Override
    public McUser retrieveUserByUsername(String username) {
        return userDao.getUserByUsername(username);
    }

    /**
     * 专用于ShiroRealm中获取用户，角色，权限
     *
     * @param username
     * @return
     */
    public McUser retrieveUserWithRoleByUsernames(String username) {
        McUser mcUser = userDao.getUserByUsername(username);
        Set<Role> roleSet = Objects.requireNonNull(mcUser).getRoles();
        if (!CollectionUtil.isSetEmpty(roleSet)) {
            for (Role role : roleSet) {
                Set<Permission> permissionSet = role.getPermissions();
                if (!CollectionUtil.isSetEmpty(permissionSet))
                    role.setPermissions(permissionSet);
            }
            mcUser.setRoles(roleSet);
        }
        return mcUser;
    }

    @Override
    @RequestMapping("/adduser")
    public void addUser(McUser user, Long roleId) {
        String encodePassword = SecurityHandler.encodePassword(user.getPassword(), user.getUsername());
        user.setPassword(encodePassword);
        if (StringUtil.isBlank(user.getStatus()))
            user.setStatus(CommonConstant.STATUS_ONE);

        Set<Role> roleSet = new HashSet<>();
        Role role1 = roleDao.get(roleId);
        if (null == role1)
            throw new NullPointerException(CommonConstant.MSG_ROLE_EXCEPTION);
        roleSet.add(role1);
        user.setRoles(roleSet);
        user.setLoginCount(0);
        user.setNickName(user.getUsername());
        this.addObject(user);
    }

    @Override
    public void modifyUser(McUser user, Long roleId) {
        // 在同一个业务中（同个session），不能存在同ID实体进行更新操作！
        McUser user0 = retrieveObject(user.getId());

        Set<Role> role = user0.getRoles();
        if (null != role) {
            Iterator<Role> iterator = role.iterator();
            if (!iterator.hasNext() || iterator.next().getId().intValue() != roleId.intValue()) {
                Set<Role> roleSet = new HashSet<>();
                Role role1 = roleDao.get(roleId);
                if (null == role1)
                    throw new NullPointerException(CommonConstant.MSG_ROLE_EXCEPTION);
                roleSet.add(role1);
                user0.setRoles(roleSet);
            }
        } else {
            Set<Role> roleSet = new HashSet<>();
            Role role1 = roleDao.get(roleId);
            if (null == role1)
                throw new NullPointerException(CommonConstant.MSG_ROLE_EXCEPTION);
            roleSet.add(role1);
            user0.setRoles(roleSet);
        }

        user0.setMobilePhone(user.getMobilePhone());
//		user0.setNickName(user.getNickName());
        user0.setRealName(user.getRealName());
        user0.setStatus(user.getStatus());
        user0.setEditor(userDao.getCurrentMcUser());
        user0.setEditTime(new Date());
        //修改用户等级和地区
        user0.setAreaId(user.getAreaId());
        user0.setUserLevel(user.getUserLevel());
        user0.setArea(user.getArea());
        user0.setCity(user.getCity());
        user0.setCityId(user.getCityId());
        user0.setProvince(user.getProvince());
        user0.setProvinceId(user.getProvinceId());
        user0.setCry(user.getCry());
        user0.setCty(user.getCty());
        user0.setCountryId(user.getCountryId());
        user0.setCountyId(user.getCountyId());
        user0.setName(user.getName());
        user0.setVillageId(user.getVillageId());
        user0.setRemarks(user.getRemarks());
        user0.setEmail(user.getEmail());
        user0.setAreaCodes(user.getAreaCodes());
        user0.setType(user.getType());
        user0.setCheckState(user.getCheckState());
        this.modifyObject(user0);
    }

    /*
     * (non-Javadoc)
     *
     * @see cc.messcat.service.system.UserService#modifyPasswordUser(cc.messcat.
     * entity.system.McUser, java.lang.String)
     */
    @Override
    public int modifyPasswordUser(McUser user, String authPassword, String oldPassword,HttpSession session) {
    	Long currentUserId = null;
    	if(user == null || user.getId() == null) {
    		currentUserId = (Long)session.getAttribute("userId");
    	} else {
    		currentUserId = user.getId();
    	}
    	
        McUser user0 = userDao.get(currentUserId);
        if (null == user0)
            throw new NullPointerException(CommonConstant.MSG_USER_NOEXIST_ERROR);
        if (StringUtil.isBlank(authPassword))
            throw new NullPointerException(CommonConstant.MSG_PASSWORD_FORMAT_ERROR);
        if (StringUtil.isBlank(oldPassword))
            throw new NullPointerException(CommonConstant.MSG_PASSWORD_FORMAT_ERROR);
        if (!SecurityHandler.verifyPassword(user0.getUsername(), oldPassword, user0.getPassword()))
//			throw new NullPointerException(CommonConstant.MSG_PASSWORD_FORMAT_ERROR);
            return 0;
        if (user0.getId().longValue() != currentUserId.longValue()) {
            user0 = this.retrieveObject(currentUserId);
            if (null == user0)
                throw new NullPointerException(CommonConstant.MSG_USER_NOEXIST_ERROR);
        }
        String encodePassword = SecurityHandler.encodePassword(authPassword, user0.getUsername());
        user0.setPassword(encodePassword);
        user0.setEditor(userDao.getCurrentMcUser());
        user0.setEditTime(new Date());
        this.modifyObject(user0);
        return 1;
    }

    /**
     *
     */
    @Override
    public List<Map<String,Object>> listByIDs(String praise) {
        return userDao.listByIDs(praise);
    }

    @Override
    public void removeUser(Long id) {
        removeObject(id);
    }

    @Override
    public boolean verifyOldPassword(String username, String oldPassword) {

        if (StringUtil.isBlank(username)) {
            return false;
        }

        if (StringUtil.isBlank(oldPassword)) {
            return false;
        }

        McUser user = retrieveUserByUsername(username);
        return user != null && !StringUtil.isBlank(user.getPassword())
                && SecurityHandler.verifyPassword(username, oldPassword, user.getPassword());

    }


    private List<McUser> retrieveUserAll() {
        List<McUser> list = retrieveAllObjects();
        for (McUser u : list) {
            if (0L != u.getAreaId()) {
                Area area0 = areaDao.getByID(u.getAreaId());
                u.setArea(area0);
            }
        }
        return list;
    }

    public Pager<McUser> retrieveUserAll(Integer pageNo, Integer pageSize) {
        return getPager(pageNo, pageSize, retrieveUserAll(), null);
    }

    /*
     * (non-Javadoc)
     *
     * @see cc.messcat.service.system.UserService#login()
     */
    @Override
    public McUser modifyForLogin(String username) {
        McUser mcUser = userDao.getUserByUsername(username);
        mcUser.setLastLogin(new Date());
        mcUser.setLoginCount(mcUser.getLoginCount() + 1);
        super.modifyObject(mcUser);
        return mcUser;
    }

//	@Override
//	public List<McUser> listByRoleArea(Area area) {
//		// TODO Auto-generated method stub
//		return userDao.listByRoleArea(area);
//	}

    @Override
    public List<McUser> listByUserArea(Area area) {
        List<McUser> list = userDao.listByUserArea(area);
        for (McUser u : list) {
            if (0L != u.getAreaId()) {
                Area area0 = areaDao.getByID(u.getAreaId());
                u.setArea(area0);
            }
        }
        return list;
    }

    @Override
    public Pager<McUser> getPage(Integer pageNo, Integer pageSize, String username, String realName,
                                 String mobilePhone, String email, McUser user, McUser loginuser, Long countryId, Long villageId,String checkState) {
        Map map = new HashMap<>();
        StringBuffer hql = new StringBuffer();
        hql.append("FROM McUser WHERE 1=1 ");
        if (username != null && !"".equals(username)) {
            username = username.replaceAll(" ", "");
            hql.append(" AND username like '%" + username + "%'");
        }
        if (realName != null && !"".equals(realName)) {
            realName = realName.replaceAll(" ", "");
            hql.append(" AND realName like '%" + realName + "%'");
        }
        if (mobilePhone != null && !"".equals(mobilePhone)) {
            mobilePhone = mobilePhone.replaceAll(" ", "");
            hql.append(" AND mobilePhone like '%" + mobilePhone + "%'");
        }
        if (email != null && !"".equals(email)) {
            mobilePhone = mobilePhone.replaceAll(" ", "");
            hql.append(" AND email like '%" + email + "%'");
        }
        //审核状态
        if(StringUtil.isNotBlank(checkState)){
        	checkState = checkState.replaceAll(" ", "");
            hql.append(" AND checkState = '" + checkState + "'");
        }
        if (BeanUtil.isValid(user)) {
            if (BeanUtil.isValid(user.getProvince()))
                hql.append(" AND province like '%" + user.getProvince() + "%'");
            if (BeanUtil.isValid(user.getCity()))
                hql.append(" AND city like '%" + user.getCity() + "%'");         
            if (BeanUtil.isValid(user.getCty()))
                hql.append(" AND cty like '%" + user.getCty() + "%'");
            if (BeanUtil.isValid(user.getCry())) {
            	Area area = areaDao.getAreaByCode(user.getCry());
            	if(area != null) hql.append(" AND cry like '%" + area.getArea() + "%'");
            }
            
            if(loginuser.getUserLevel().getLevel() == 4){
            	if(BeanUtil.isValid(user.getCry())){
         		   Area area = areaDao.getAreaByCode(user.getCry());
                   hql.append(" AND cry like '%" + area.getArea() + "%'");
         	   }else{
         		   Area area = areaDao.getAreaByCode(loginuser.getCry());
                   String cry = area.getArea(); 
                    hql.append(" AND cry like '%" + cry + "%'");
         	   }
            }else{
            	if(BeanUtil.isValid(loginuser.getCry())){
          		   Area area = areaDao.getAreaByName(loginuser.getCry());
                    hql.append(" AND cry like '%" + area.getArea() + "%'");
          	    }
            }
            
            if(loginuser.getUserLevel().getLevel() == 5){
            	if(BeanUtil.isValid(loginuser.getName())){
         		   Area area = areaDao.getAreaByCode(loginuser.getArea().getAreaCode());
                   hql.append(" AND name like '%" + area.getArea() + "%'");
         	   }else{
         		   Area area = areaDao.getAreaByCode(loginuser.getName());
                   String cry = area.getArea(); 
                    hql.append(" AND name like '%" + cry + "%'");
         	   }
            }else{
            	if(BeanUtil.isValid(user.getName())){
          		   Area area = areaDao.getAreaByCode(user.getName());
                    hql.append(" AND name like '%" + area.getArea() + "%'");
          	    }
            }
            
           /* if (BeanUtil.isValid(user.getCry()))
                hql.append(" AND cry like '%" + user.getCry() + "%'");   
            if (BeanUtil.isValid(user.getName()))
                hql.append(" AND name like '%" + user.getName() + "%'");*/
           /* if (BeanUtil.isValid(user.getCry())&&BeanUtil.isValid(user.getName()))
                hql.append("AND fatherId="+user.getCry()+" AND id =" + user.getName() + "");*/
        }
        //数据显示控制
        if (loginuser != null) {
            if (loginuser.getUserLevel() != null) {
                Integer level = loginuser.getUserLevel().getLevel();

                if (level.intValue() == 4) {
                    hql.append(" AND areaId in (select id from Area where fatherId=" + loginuser.getAreaId() + ")");
                    if (villageId != null) {
                        hql.append(" and areaId=" + villageId);
                    }
                } else if (level.intValue() == 5) {//村级别无法查看
                    return new Pager<>();
                } else if (countryId != null || villageId != null) {
                    if (villageId != null) {
                        hql.append(" and areaId=" + villageId);
                    } else {
                        hql.append(" AND areaId in (select id from Area where fatherId=" + countryId + ")");
                    }
                }
            }
        }

        return this.areaDao.getPagerByHql(pageNo, pageSize, hql.toString(), map);
    }

	/**
	 * 用户名校验
	 * @param username
	 * @return
	 */
	@Override
	public List<McUser> verifyUsername(String username) {
		Map<String,String> condition = new HashMap<>();
		condition.put("username", username);
		return userDao.queryList(" from McUser where username= :username",condition);
	}

	@Override
	public void addUserByPhone(McUser user) {
		String encodePassword = SecurityHandler.encodePassword(user.getPassword(), user.getUsername());
        user.setPassword(encodePassword);
        user.setStatus(CommonConstant.STATUS_ONE);
        this.addObject(user);
	}

}
